package com.supermap.mouseListeners;

import com.supermap.Helper;
import com.supermap.MainFrame;
import com.supermap.consts.AttrConsts;
import com.supermap.data.*;
import com.supermap.data.conversion.*;
import com.supermap.dialogs.FieldInfoManageDialog;
import com.supermap.dialogs.InputNameDialog;
import com.supermap.dialogs.ProcessBarDialog;
import com.supermap.mapping.LayerSettingVector;
import com.supermap.mapping.Map;
import com.supermap.realspace.Layer3DSettingVector;
import com.supermap.realspace.Layer3DType;
import com.supermap.realspace.Scene;
import com.supermap.ui.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;

public class WorkspaceTreeMouseListener implements MouseListener {
    private final MainFrame mainFrame;
    private final WorkspaceTree workspaceTree;
    private final JTabbedPane mainPane;
    private final JSplitPane treeSplitPane;
    private final JSplitPane dataPane;
    private final JSplitPane settingPane;

    public WorkspaceTreeMouseListener(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
        this.workspaceTree = this.mainFrame.getWorkspaceTree();
        this.mainPane = this.mainFrame.getMainPane();
        this.treeSplitPane = this.mainFrame.getTreeSplitPane();
        this.dataPane = this.mainFrame.getDataPane();
        this.settingPane = this.mainFrame.getSettingPane();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        Object source = e.getSource();
        if (!(source instanceof WorkspaceTree)) {
            return;
        }
        WorkspaceTree workspaceTree = (WorkspaceTree) source;
        JPopupMenu popupMenu = workspaceTree.getComponentPopupMenu();
        if (popupMenu != null) {
            popupMenu.removeAll();
            popupMenu.setVisible(false);
        }

        switch (e.getButton()) {
            // 鼠标左键
            case MouseEvent.BUTTON1:

                // 双击鼠标左键
                if (e.getClickCount() == 2) {
                    TreeNodeData selectedTreeNode = Helper.getSelectedTreeNode(workspaceTree);
                    if (selectedTreeNode == null) {
                        return;
                    }

                    NodeDataType type = selectedTreeNode.getType();

                    // 打开地图
                    if (type == NodeDataType.MAPNAME) {
                        String mapName = selectedTreeNode.getData().toString();
                        MapControl mapControl = Helper.createMapControl(mapName, mainPane, workspaceTree, mainFrame.getMapScaledLabel());
                        mainPane.setSelectedComponent(mapControl);
                        Helper.createLayersTree(mainFrame, mapControl.getMap());
                        Helper.updateComponentsEnabled(new Component[]{mainFrame.objectOperateMenu, mainFrame.transportationMenu}, true);
                        openMap(mapName);
                    }
                    // 打开场景
                    else if (type == NodeDataType.SCENENAME) {
                        String sceneName = selectedTreeNode.getData().toString();
                        SceneControl sceneControl = Helper.createSceneControl(sceneName, mainPane, workspaceTree);
                        mainPane.setSelectedComponent(sceneControl);
                        Helper.createLayer3DsTree(mainFrame, sceneControl.getScene());
                        Helper.updateComponentsEnabled(new Component[]{mainFrame.styleSettingMenu, mainFrame.space3DAnalystMenu}, true);
                        openScene(sceneName);
                    }
                    // 打开矢量数据
                    else if (type == NodeDataType.DATASETVECTOR) {
                        Object nodeData = selectedTreeNode.getData();
                        if (nodeData instanceof DatasetVector) {
                            DatasetVector datasetVector = (DatasetVector) nodeData;
                            DatasetType datasetType = datasetVector.getType();
                            // 属性表
                            if (datasetType == DatasetType.TABULAR) {
                                Recordset recordset = datasetVector.getRecordset(false, CursorType.DYNAMIC);
                                JTable table = new JTable();
                                Helper.loadTabular(recordset, table);
                                JScrollPane scrollPane = new JScrollPane(table);
                                mainPane.addTab(datasetVector.getName() + " 属性表", scrollPane);
                            }
                            // 双击矢量数据新建地图并显示
                            else {
                                Helper.addDatasetToNewMap(datasetVector, mainFrame);
                            }
                        }
                    }
                    // 打开栅格、图片数据
                    else if (type == NodeDataType.DATASETGRID || type == NodeDataType.DATASETIMAGE) {
                        Object nodeData = selectedTreeNode.getData();
                        if (nodeData instanceof Dataset) {
                            Helper.addDatasetToNewMap((Dataset) nodeData, mainFrame);
                        }
                    }
                }
                break;
            // 鼠标中键
            case MouseEvent.BUTTON2:
                break;
            // 鼠标右键
            case MouseEvent.BUTTON3:
                if (popupMenu == null) {
                    popupMenu = new JPopupMenu();
                    workspaceTree.setComponentPopupMenu(popupMenu);
                    popupMenu.setLocation(e.getLocationOnScreen());
                } else {
                    popupMenu.removeAll();
                    popupMenu.setVisible(false);
                }
                TreeNodeData selectedTreeNode = Helper.getSelectedTreeNode(workspaceTree);
                if (selectedTreeNode == null) {
                    return;
                }
                NodeDataType type = selectedTreeNode.getType();
                // 工作空间右键菜单
                if (type == NodeDataType.WORKSPACE) {
                    initWorkspaceContextMenu(popupMenu);
                }
                // 数据源右键菜单
                else if (type == NodeDataType.DATASOURCES) {
                    initDatasourcesContextMenu(popupMenu);
                }
                // 地图右键菜单
                else if (type == NodeDataType.MAPS) {
                    initMapsContextMenu(popupMenu);
                }
                // 地图列表选项右键菜单
                else if (type == NodeDataType.MAPNAME) {
                    initMapContextMenu(popupMenu, selectedTreeNode);
                }
                // 场景右键菜单
                else if (type == NodeDataType.SCENES) {
                    initScenesContextMenu(popupMenu);
                }
                // 场景列表选项右键菜单
                else if (type == NodeDataType.SCENENAME) {
                    initSceneContextMenu(popupMenu, selectedTreeNode);
                }
                // 矢量数据集右键菜单
                else if (type == NodeDataType.DATASETVECTOR || type == NodeDataType.DATASETGRID) {
                    initDatasetVectorContextMenu(popupMenu, selectedTreeNode);
                }
                // 数据源右键菜单
                else if (type == NodeDataType.DATASOURCE) {
                    initDatasourceContextMenu(popupMenu, selectedTreeNode);
                }
                break;
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    /**
     * 打开地图
     *
     * @param mapName 地图名称
     */
    private void openMap(String mapName) {
        Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
        if (bottomComponent instanceof LayersTree) {
            LayersTree layersTree = (LayersTree) bottomComponent;
            Map map = layersTree.getMap();
            map.close();
            map.open(mapName);
            layersTree.reload();
        }
    }

    private void openScene(String sceneName) {
        Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
        if (bottomComponent instanceof Layer3DsTree) {
            Layer3DsTree layer3DsTree = (Layer3DsTree) bottomComponent;
            Scene scene = layer3DsTree.getScene();
            scene.close();
            scene.open(sceneName);
            layer3DsTree.reload();
        }
    }

    /**
     * 初始化工作空间右键菜单
     *
     * @param popupMenu 鼠标右键菜单对象
     */
    private void initWorkspaceContextMenu(JPopupMenu popupMenu) {
        JMenuItem openWorkspaceItem = new JMenuItem("打开工作空间");
        openWorkspaceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            Helper.openWorkspaceFile(frame, workspaceTree);
        });
        popupMenu.add(openWorkspaceItem);

        JMenuItem closeWorkspaceItem = new JMenuItem("关闭工作空间");
        closeWorkspaceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            workspaceTree.getWorkspace().close();
            Helper.updateComponentsEnabled(new Component[]{mainFrame.dataOperateMenu, mainFrame.queryMenu, mainFrame.projMenu, mainFrame.analystMenu, mainFrame.spatialStatisticsMenu}, false);
        });
        popupMenu.add(closeWorkspaceItem);

        popupMenu.setVisible(true);
    }

    /**
     * 初始化数据源根节点右键菜单
     *
     * @param popupMenu 鼠标右键菜单对象
     */
    private void initDatasourcesContextMenu(JPopupMenu popupMenu) {
        JMenuItem openFileDatasourceItem = new JMenuItem("打开文件型数据源");
        openFileDatasourceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Workspace workspace = workspaceTree.getWorkspace();
            if (workspace == null) {
                return;
            }

            // 新建文件型数据源名称
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            FileDialog openFileDatasourceDialog = new FileDialog(frame, "打开文件型数据源", FileDialog.LOAD);
            String openedDatasourceFilePath = Helper.getFilePathFromFileDialog(openFileDatasourceDialog, AttrConsts.DATASOURCE_FILTER);
            if (openedDatasourceFilePath == null) {
                return;
            }

            DatasourceConnectionInfo openedDatasourceConnectionInfo = new DatasourceConnectionInfo();
            openedDatasourceConnectionInfo.setServer(openedDatasourceFilePath);
            String fileName = new File(openedDatasourceFilePath).getName();
            String[] strings = fileName.split("\\.");
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < strings.length - 1; i++) {
                stringBuilder.append(strings[i]);
            }
            String openedDatasourceAlias = stringBuilder.toString();
            openedDatasourceConnectionInfo.setAlias(openedDatasourceAlias);
            if (openedDatasourceFilePath.endsWith(AttrConsts.UDB_SUFFIX)) {
                openedDatasourceConnectionInfo.setEngineType(EngineType.UDB);
            } else {
                openedDatasourceConnectionInfo.setEngineType(EngineType.UDBX);
            }

            boolean isExistedSameName = false;
            Datasources datasources = workspace.getDatasources();
            for (int i = 0; i < datasources.getCount(); i++) {
                if (openedDatasourceAlias.equalsIgnoreCase(datasources.get(i).getAlias())) {
                    isExistedSameName = true;
                    break;
                }
            }
            if (isExistedSameName) {
                JOptionPane.showMessageDialog(frame, "已经打开同名数据源！请先关闭同名数据源后再尝试打开！",
                        "打开文件型数据源", JOptionPane.WARNING_MESSAGE);
            } else {
                datasources.open(openedDatasourceConnectionInfo);
                Helper.updateComponentsEnabled(new Component[]{mainFrame.dataOperateMenu, mainFrame.queryMenu, mainFrame.projMenu, mainFrame.analystMenu, mainFrame.spatialStatisticsMenu}, true);
            }
        });
        popupMenu.add(openFileDatasourceItem);

        JMenuItem createFileDatasourceItem = new JMenuItem("新建文件型数据源");
        createFileDatasourceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Workspace workspace = workspaceTree.getWorkspace();
            if (workspace == null) {
                return;
            }

            // 新建文件型数据源名称
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            FileDialog fileDialog = new FileDialog(frame, "新建文件型数据源", FileDialog.SAVE);
            String newDatasourceFilePath = Helper.getFilePathFromFileDialog(fileDialog, AttrConsts.DATASOURCE_FILTER);
            if (newDatasourceFilePath == null) {
                return;
            }

            // 新建数据源若已存在，则先删除原来的数据源再新建
            File newDatasourceFile = new File(newDatasourceFilePath);
            if (newDatasourceFile.exists()) {
                try {
                    Files.delete(Paths.get(URI.create(newDatasourceFilePath)));
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }

            DatasourceConnectionInfo newDatasourceConnectionInfo = new DatasourceConnectionInfo();
            newDatasourceConnectionInfo.setServer(newDatasourceFilePath);
            String fileName = newDatasourceFile.getName();
            String[] strings = fileName.split("\\.");
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < strings.length - 1; i++) {
                stringBuilder.append(strings[i]);
            }
            newDatasourceConnectionInfo.setAlias(stringBuilder.toString());
            if (newDatasourceFilePath.endsWith(AttrConsts.UDB_SUFFIX)) {
                newDatasourceConnectionInfo.setEngineType(EngineType.UDB);
            } else {
                newDatasourceConnectionInfo.setEngineType(EngineType.UDBX);
            }
            workspace.getDatasources().create(newDatasourceConnectionInfo);
            Helper.updateComponentsEnabled(new Component[]{mainFrame.dataOperateMenu, mainFrame.queryMenu, mainFrame.projMenu, mainFrame.analystMenu, mainFrame.spatialStatisticsMenu}, true);
        });
        popupMenu.add(createFileDatasourceItem);

        JMenuItem createMemoryDatasourceItem = new JMenuItem("新建内存数据源");
        createMemoryDatasourceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Workspace workspace = workspaceTree.getWorkspace();
            if (workspace == null) {
                return;
            }

            // 新建内存数据源名称
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog inputNameDialog = new InputNameDialog(frame, "新建内存数据源", true);
            inputNameDialog.setVisible(true);
            String newDatasourceName = inputNameDialog.getInputText();
            inputNameDialog.dispose();
            if (newDatasourceName.equals(AttrConsts.EMPTY)) {
                return;
            }

            DatasourceConnectionInfo newDatasourceConnectionInfo = new DatasourceConnectionInfo();
            newDatasourceConnectionInfo.setAlias(newDatasourceName);
            newDatasourceConnectionInfo.setEngineType(EngineType.MEMORY);
            workspace.getDatasources().create(newDatasourceConnectionInfo);
            Helper.updateComponentsEnabled(new Component[]{mainFrame.dataOperateMenu, mainFrame.queryMenu, mainFrame.projMenu, mainFrame.analystMenu, mainFrame.spatialStatisticsMenu}, true);
        });
        popupMenu.add(createMemoryDatasourceItem);

        popupMenu.setVisible(true);
    }

    /**
     * 初始化地图根节点右键菜单
     *
     * @param popupMenu 鼠标右键菜单对象
     */
    private void initMapsContextMenu(JPopupMenu popupMenu) {
        JMenuItem createNewMapItem = new JMenuItem("新建地图");
        createNewMapItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Workspace workspace = workspaceTree.getWorkspace();
            if (workspace == null) {
                return;
            }

            // 新建地图名称对话框
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog inputMapNameDialog = new InputNameDialog(frame, "新建地图", true);
            inputMapNameDialog.setVisible(true);
            String newMapName = inputMapNameDialog.getInputText();
            inputMapNameDialog.dispose();
            if (newMapName.equals(AttrConsts.EMPTY)) {
                return;
            }

            MapControl newMapControl = Helper.createMapControl(newMapName, mainPane, workspaceTree, mainFrame.getMapScaledLabel());
            LayersTree layersTree = new LayersTree(newMapControl.getMap());
            layersTree.addMouseListener(new LayersTreeMouseListener(layersTree, dataPane, settingPane));
            treeSplitPane.setBottomComponent(new JScrollPane(layersTree));
            mainPane.setSelectedComponent(newMapControl);
            Maps maps = workspace.getMaps();
            maps.add(newMapName, newMapControl.getMap().toXML(), workspace.getVersion());
        });
        popupMenu.add(createNewMapItem);

        popupMenu.setVisible(true);
    }

    /**
     * 初始化地图列表选项鼠标右键菜单
     *
     * @param popupMenu        鼠标右键菜单对象
     * @param selectedTreeNode 选中节点
     */
    private void initMapContextMenu(JPopupMenu popupMenu, TreeNodeData selectedTreeNode) {
        // 打开地图
        JMenuItem openMapItem = new JMenuItem("打开地图");
        openMapItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            String mapName = selectedTreeNode.getData().toString();
            MapControl newMapControl = Helper.createMapControl(mapName, mainPane, workspaceTree, mainFrame.getMapScaledLabel());
            LayersTree layersTree = new LayersTree(newMapControl.getMap());
            layersTree.addMouseListener(new LayersTreeMouseListener(layersTree, dataPane, settingPane));
            treeSplitPane.setBottomComponent(new JScrollPane(layersTree));
            mainPane.setSelectedComponent(newMapControl);
            openMap(mapName);
        });
        popupMenu.add(openMapItem);

        // 关闭地图
        JMenuItem closeMapItem = new JMenuItem("关闭地图");
        closeMapItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            if (!(bottomComponent instanceof LayersTree)) {
                return;
            }

            LayersTree layersTree = (LayersTree) bottomComponent;
            Map map = layersTree.getMap();
            mainPane.remove(map.getMapControl());
            map.close();
            layersTree.reload();
            Helper.updateComponentsEnabled(new Component[]{mainFrame.objectOperateMenu, mainFrame.transportationMenu}, false);
        });
        popupMenu.add(closeMapItem);

        JMenuItem renameItem = new JMenuItem("重命名");
        renameItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            if (!(bottomComponent instanceof LayersTree)) {
                return;
            }

            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog renameMapDialog = new InputNameDialog(frame, "地图重命名", true);
            renameMapDialog.setVisible(true);
            String newMapName = renameMapDialog.getInputText();
            renameMapDialog.dispose();
            if (newMapName.equals(AttrConsts.EMPTY)) {
                return;
            }

            String oldMapName = selectedTreeNode.getData().toString();
            workspaceTree.getWorkspace().getMaps().rename(oldMapName, newMapName);
        });
        popupMenu.add(renameItem);

        JMenuItem addToNewSceneItem = new JMenuItem("添加到新场景");
        addToNewSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            SceneControl sceneControl = Helper.createSceneControl(null, mainPane, workspaceTree);
            Scene scene = sceneControl.getScene();
            String mapName = selectedTreeNode.getData().toString();
            scene.getLayers().add(mapName, Layer3DType.MAP, true);
            scene.viewEntire();
            scene.refresh();
            Layer3DsTree layer3DsTree = new Layer3DsTree(scene);
            layer3DsTree.addMouseListener(new Layer3DsTreeMouseListener(layer3DsTree));
            treeSplitPane.setBottomComponent(new JScrollPane(layer3DsTree));
            mainPane.setSelectedComponent(sceneControl);
            layer3DsTree.reload();
            mainPane.setSelectedComponent(sceneControl);
            Helper.updateComponentsEnabled(new Component[]{mainFrame.styleSettingMenu, mainFrame.space3DAnalystMenu}, true);
        });
        popupMenu.add(addToNewSceneItem);

        JMenuItem addToCurrentSceneItem = new JMenuItem("添加到当前场景");
        addToCurrentSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            if (!(bottomComponent instanceof Layer3DsTree)) {
                return;
            }
            Layer3DsTree layer3DsTree = (Layer3DsTree) bottomComponent;
            Scene scene = layer3DsTree.getScene();
            if (scene == null) {
                return;
            }

            String mapName = selectedTreeNode.getData().toString();
            scene.getLayers().add(mapName, Layer3DType.MAP, true);
            scene.refresh();
        });
        if (mainPane.getSelectedIndex() != -1) {
            Component selectedComponent = mainPane.getSelectedComponent();
            addToCurrentSceneItem.setEnabled(selectedComponent instanceof SceneControl);
        } else {
            addToCurrentSceneItem.setEnabled(false);
        }
        popupMenu.add(addToCurrentSceneItem);

        popupMenu.setVisible(true);
    }

    private void initScenesContextMenu(JPopupMenu popupMenu) {
        JMenuItem createNewSphereSceneItem = new JMenuItem("新建球面场景");
        createNewSphereSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Workspace workspace = workspaceTree.getWorkspace();
            if (workspace == null) {
                return;
            }

            // 新建球面场景名称对话框
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog inputSceneNameDialog = new InputNameDialog(frame, "新建球面场景", true);
            inputSceneNameDialog.setVisible(true);
            String newSceneName = inputSceneNameDialog.getInputText();
            inputSceneNameDialog.dispose();
            if (newSceneName.equals(AttrConsts.EMPTY)) {
                return;
            }

            SceneControl newSceneControl = Helper.createSceneControl(newSceneName, mainPane, workspaceTree);
            Layer3DsTree layer3DsTree = new Layer3DsTree(newSceneControl.getScene());
            layer3DsTree.addMouseListener(new Layer3DsTreeMouseListener(layer3DsTree));
            treeSplitPane.setBottomComponent(new JScrollPane(layer3DsTree));
            mainPane.setSelectedComponent(newSceneControl);
            workspace.getScenes().add(newSceneName, newSceneControl.getScene().toXML());
            workspaceTree.reload();
            Helper.updateComponentsEnabled(new Component[]{mainFrame.styleSettingMenu, mainFrame.space3DAnalystMenu}, true);
        });
        popupMenu.add(createNewSphereSceneItem);
    }

    private void initSceneContextMenu(JPopupMenu popupMenu, TreeNodeData selectedTreeNode) {
        // 打开地图
        JMenuItem openSphereSceneItem = new JMenuItem("打开球面场景");
        openSphereSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            String sceneName = selectedTreeNode.getData().toString();
            SceneControl newSceneControl = Helper.createSceneControl(sceneName, mainPane, workspaceTree);
            Layer3DsTree layer3DsTree = new Layer3DsTree(newSceneControl.getScene());
            layer3DsTree.addMouseListener(new Layer3DsTreeMouseListener(layer3DsTree));
            treeSplitPane.setBottomComponent(new JScrollPane(layer3DsTree));
            mainPane.setSelectedComponent(newSceneControl);
            openScene(sceneName);
        });
        popupMenu.add(openSphereSceneItem);

        // 关闭地图
        JMenuItem closeSceneItem = new JMenuItem("关闭场景");
        closeSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            if (!(bottomComponent instanceof Layer3DsTree)) {
                return;
            }

            Layer3DsTree layer3DsTree = (Layer3DsTree) bottomComponent;
            Scene scene = layer3DsTree.getScene();
            if (scene == null) {
                return;
            }

            SceneControl sceneControl = getCurrentSceneControl(scene);
            if (sceneControl != null) {
                mainPane.remove(sceneControl);
            }
            scene.close();
            layer3DsTree.reload();
            Helper.updateComponentsEnabled(new Component[]{mainFrame.styleSettingMenu, mainFrame.space3DAnalystMenu}, false);
        });
        popupMenu.add(closeSceneItem);

        JMenuItem renameItem = new JMenuItem("重命名");
        renameItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            if (!(bottomComponent instanceof Layer3DsTree)) {
                return;
            }

            Layer3DsTree layer3DsTree = (Layer3DsTree) bottomComponent;
            Scene scene = layer3DsTree.getScene();
            if (scene == null) {
                return;
            }

            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog renameMapDialog = new InputNameDialog(frame, "场景重命名", true);
            renameMapDialog.setVisible(true);
            String newSceneName = renameMapDialog.getInputText();
            renameMapDialog.dispose();
            if (newSceneName.equals(AttrConsts.EMPTY)) {
                return;
            }

            String oldSceneName = selectedTreeNode.getData().toString();
            workspaceTree.getWorkspace().getScenes().rename(oldSceneName, newSceneName);
        });
        popupMenu.add(renameItem);

        popupMenu.setVisible(true);
    }

    private SceneControl getCurrentSceneControl(Scene scene) {
        Component[] components = mainPane.getComponents();
        if (components != null) {
            for (Component component : components) {
                if (component instanceof SceneControl) {
                    SceneControl sceneControl = (SceneControl) component;
                    if (sceneControl.getScene() == scene) {
                        return sceneControl;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 初始化矢量数据集鼠标右键菜单
     *
     * @param popupMenu        鼠标右键菜单对象
     * @param selectedTreeNode 选中节点
     */
    private void initDatasetVectorContextMenu(JPopupMenu popupMenu, TreeNodeData selectedTreeNode) {
        Dataset dataset = (Dataset) selectedTreeNode.getData();
        JMenuItem openTabularItem = new JMenuItem("浏览属性表");
        openTabularItem.setVisible(dataset instanceof DatasetVector);
        openTabularItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            DatasetVector datasetVector = (DatasetVector) selectedTreeNode.getData();
            Recordset recordset = datasetVector.getRecordset(false, CursorType.DYNAMIC);
            JTable table = new JTable();
            Helper.loadTabular(recordset, table);
            JScrollPane scrollPane = new JScrollPane(table);
            mainPane.addTab(datasetVector.getName() + " 属性表", scrollPane);
            mainPane.setSelectedComponent(scrollPane);
        });
        popupMenu.add(openTabularItem);

        JMenuItem addToNewMapItem = new JMenuItem("添加到新地图");
        addToNewMapItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Helper.addDatasetToNewMap(dataset, mainFrame);
        });
        popupMenu.add(addToNewMapItem);

        JMenuItem addToCurrentMapItem = new JMenuItem("添加到当前地图");
        addToCurrentMapItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            LayersTree layersTree = (LayersTree) bottomComponent;
            Map mapView = layersTree.getMap();
            if (mapView == null) {
                return;
            }

            SwingUtilities.invokeLater(() -> {
                mapView.getLayers().add(dataset, new LayerSettingVector(), true);
                mapView.refresh();
                layersTree.reload();
            });
        });
        if (mainPane.getSelectedIndex() != -1) {
            Component selectedComponent = mainPane.getSelectedComponent();
            addToCurrentMapItem.setEnabled(selectedComponent instanceof MapControl);
        } else {
            addToCurrentMapItem.setEnabled(false);
        }
        popupMenu.add(addToCurrentMapItem);

        JMenuItem addToNewSceneItem = new JMenuItem("添加到新场景");
        addToNewSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Helper.addDatasetToNewScene(dataset, mainFrame);
        });
        popupMenu.add(addToNewSceneItem);

        JMenuItem addToCurrentSceneItem = new JMenuItem("添加到当前场景");
        addToCurrentSceneItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Component bottomComponent = ((JScrollPane) treeSplitPane.getBottomComponent()).getViewport().getView();
            Layer3DsTree layer3DsTree = (Layer3DsTree) bottomComponent;
            Scene scene = layer3DsTree.getScene();
            if (scene == null) {
                return;
            }

            SwingUtilities.invokeLater(() -> {
                scene.getLayers().add(dataset, new Layer3DSettingVector(), true);
                scene.refresh();
                layer3DsTree.reload();
            });
        });
        if (mainPane.getSelectedIndex() != -1) {
            Component selectedComponent = mainPane.getSelectedComponent();
            addToCurrentSceneItem.setEnabled(selectedComponent instanceof SceneControl);
        } else {
            addToCurrentSceneItem.setEnabled(false);
        }
        popupMenu.add(addToCurrentSceneItem);

        JMenuItem exportDataItem = new JMenuItem("导出数据集");
        exportDataItem.setVisible(dataset instanceof DatasetVector);
        exportDataItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            DatasetVector datasetVector = (DatasetVector) selectedTreeNode.getData();
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            FileDialog exportDataFileDialog = new FileDialog(frame, "导出数据集", FileDialog.SAVE);
            String exportDataFilePath = Helper.getFilePathFromFileDialog(exportDataFileDialog, AttrConsts.IMPORT_DATA_FILTER);
            if (exportDataFilePath == null) {
                return;
            }

            DataExport dataExport = new DataExport();
            ProcessBarDialog exportDataProcessDialog = new ProcessBarDialog(frame, "导出数据进度", true);
            dataExport.addExportSteppedListener(exportSteppedEvent -> {
                int subPercent = exportSteppedEvent.getSubPercent();
                exportDataProcessDialog.setValue(subPercent);
                if (subPercent == 100) {
                    exportDataProcessDialog.setVisible(false);
                    JOptionPane.showMessageDialog(frame, "缓冲区数据生成完成！", "生成缓冲区数据", JOptionPane.INFORMATION_MESSAGE);
                }
            });
            ExportSettings exportSettings = dataExport.getExportSettings();
            ExportSetting exportSetting = null;

            if (exportDataFilePath.endsWith(AttrConsts.ARCSHP_SUFFIX)) {
                exportSetting = new ExportSettingSHP();
                exportSetting.setTargetFileType(FileType.SHP);
            }

            if (exportSetting != null) {
                exportSetting.setTargetFilePath(exportDataFilePath);
                exportSetting.setSourceData(datasetVector);
                exportSetting.setOverwrite(true);
                exportSettings.add(exportSetting);
                new Thread(dataExport::run).start();
                exportDataProcessDialog.setVisible(true);
            }
        });
        popupMenu.add(exportDataItem);

        JMenuItem fieldInfoItem = new JMenuItem("属性结构");
        fieldInfoItem.setVisible(dataset instanceof DatasetVector);
        fieldInfoItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            DatasetVector datasetVector = (DatasetVector) selectedTreeNode.getData();
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            FieldInfoManageDialog fieldInfoManageDialog = new FieldInfoManageDialog(frame, "属性结构", false, datasetVector);
            fieldInfoManageDialog.setVisible(true);
        });
        popupMenu.add(fieldInfoItem);

        popupMenu.setVisible(true);
    }

    /**
     * 初始化数据源鼠标右键菜单
     *
     * @param popupMenu        鼠标右键菜单对象
     * @param selectedTreeNode 选中节点
     */
    private void initDatasourceContextMenu(JPopupMenu popupMenu, TreeNodeData selectedTreeNode) {
        JMenu createDatasetMenu = new JMenu("新建数据集");

        JMenuItem createPointDatasetItem = new JMenuItem("点数据集");
        createPointDatasetItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            createVectorDataset("新建点数据集名称", DatasetType.POINT, (Datasource) selectedTreeNode.getData());
        });
        createDatasetMenu.add(createPointDatasetItem);

        JMenuItem createLineDatasetItem = new JMenuItem("线数据集");
        createLineDatasetItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            createVectorDataset("新建线数据集名称", DatasetType.LINE, (Datasource) selectedTreeNode.getData());
        });
        createDatasetMenu.add(createLineDatasetItem);

        JMenuItem createPolygonDatasetItem = new JMenuItem("面数据集");
        createPolygonDatasetItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            createVectorDataset("新建面数据集名称", DatasetType.REGION, (Datasource) selectedTreeNode.getData());
        });
        createDatasetMenu.add(createPolygonDatasetItem);

        JMenuItem createTextDatasetItem = new JMenuItem("文本数据集");
        createTextDatasetItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            createVectorDataset("新建文本数据集名称", DatasetType.TEXT, (Datasource) selectedTreeNode.getData());
        });
        createDatasetMenu.add(createTextDatasetItem);

        popupMenu.add(createDatasetMenu);

        JMenuItem closeDatasourceItem = new JMenuItem("关闭数据源");
        closeDatasourceItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Object nodeData = selectedTreeNode.getData();
            if (nodeData instanceof Datasource) {
                Datasource datasource = (Datasource) nodeData;
                datasource.close();
            }
        });
        popupMenu.add(closeDatasourceItem);

        JMenuItem renameDatasourceItem = new JMenuItem("重命名");
        renameDatasourceItem.addActionListener(e -> {
            popupMenu.setVisible(false);

            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            InputNameDialog renameDatasourceDialog = new InputNameDialog(frame, "数据源重命名", true);
            renameDatasourceDialog.setVisible(true);
            String newAlias = renameDatasourceDialog.getInputText();
            renameDatasourceDialog.dispose();
            if (newAlias.equals(AttrConsts.EMPTY)) {
                return;
            }

            Object nodeData = selectedTreeNode.getData();
            if (nodeData instanceof Datasource) {
                Datasource datasource = (Datasource) nodeData;
                String oldAlias = datasource.getAlias();
                workspaceTree.getWorkspace().getDatasources().modifyAlias(oldAlias, newAlias);
            }
        });
        popupMenu.add(renameDatasourceItem);

        JMenuItem importDataItem = new JMenuItem("导入数据集");
        importDataItem.addActionListener(e -> {
            popupMenu.setVisible(false);
            Datasource datasource = (Datasource) selectedTreeNode.getData();
            Frame frame = (Frame) workspaceTree.getRootPane().getParent();
            FileDialog importDataFileDialog = new FileDialog(frame, "导入数据集", FileDialog.LOAD);
            String importDataFilePath = Helper.getFilePathFromFileDialog(importDataFileDialog, AttrConsts.IMPORT_DATA_FILTER);
            if (importDataFilePath == null) {
                return;
            }

            DataImport dataImport = new DataImport();
            ImportSettings importSettings = dataImport.getImportSettings();
            ImportSetting importSetting = null;

            if (importDataFilePath.endsWith(AttrConsts.ARCSHP_SUFFIX)) {
                importSetting = new ImportSettingSHP();
            } else if (importDataFilePath.endsWith(AttrConsts.OBJ_SUFFIX)) {
                importSetting = new ImportSettingModelOSG();
            }

            if (importSetting != null) {
                importSetting.setSourceFilePath(importDataFilePath);
                importSetting.setTargetDatasource(datasource);
                importSetting.setImportMode(ImportMode.NONE);
                importSettings.add(importSetting);
                dataImport.run();
            }
        });
        popupMenu.add(importDataItem);

        popupMenu.setVisible(true);
    }

    private void createVectorDataset(String title, DatasetType datasetType, Datasource datasource) {
        Frame frame = (Frame) workspaceTree.getRootPane().getParent();
        InputNameDialog createLineDatasetNameDialog = new InputNameDialog(frame, title, true);
        createLineDatasetNameDialog.setVisible(true);
        String newLineDatasetName = createLineDatasetNameDialog.getInputText();
        createLineDatasetNameDialog.dispose();

        if (newLineDatasetName.equals(AttrConsts.EMPTY)) {
            return;
        }

        DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
        datasetVectorInfo.setType(datasetType);
        datasetVectorInfo.setName(newLineDatasetName);

        datasource.getDatasets().create(datasetVectorInfo);
    }
}
